/*
	author :奈奎斯特不稳定
	date：1/13 10:09
*/
#include "lcd.h"
#include "math.h"
#include "LCD_API.h"

TypeRoate _RoateValue= {{0,0},0,1};
const int num_pos=90;//表盘上数字距离中心的位置
float clock_angle=0;//时钟旋转的角度

float shirink_size=-0;//缩小尺寸
void DrawFillCircle(u16 x0,u16 y0,u8 r,u16 color)
{
    for(int i = 0; i<r; i++)
        Draw_Circle(x0,y0,r,color);
}

//——————————————————————————————————————————————————————————————————————————————————————————————————————————
//版权声明：本文为CSDN博主「xtlisk」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。
//原文链接：https://blog.csdn.net/xtlisk/article/details/51249371

//点x，y绕x0，y0旋转angle弧度
float mySqrt(float x)
{
    float a = x;
    unsigned int i = *(unsigned int *)&x;
    i = (i + 0x3f76cf62) >> 1;
    x = *(float *)&i;
    x = (x + a / x) * 0.5;
    return x;
}
//开平方根函数
unsigned int sqrt_16(unsigned long M)
{
    unsigned int N, i;
    unsigned long tmp, ttp;   // 结果、循环计数
    if (M == 0)               // 被开方数，开方结果也为0
        return 0;
    N = 0;
    tmp = (M >> 30);          // 获取最高位：B[m-1]
    M <<= 2;
    if (tmp > 1)              // 最高位为1
    {
        N ++;                 // 结果当前位为1，否则为默认的0
        tmp -= N;
    }
    for (i=15; i>0; i--)      // 求剩余的15位
    {
        N <<= 1;              // 左移一位

        tmp <<= 2;
        tmp += (M >> 30);     // 假设

        ttp = N;
        ttp = (ttp<<1)+1;

        M <<= 2;
        if (tmp >= ttp)       // 假设成立
        {
            tmp -= ttp;
            N ++;
        }
    }
    return N;
}

//需要优化atant2 cos sin算法
static void Rotate(int x0,int y0,int*x,int*y,double angle,int direction)
{
    int temp=(*y-y0)*(*y-y0)+(*x-x0)*(*x-x0);
    double r=mySqrt(temp);
    double a0=atan2(*y-y0,*x-x0);//注意这里原来的文件是返的
    if(direction)
    {
        *x=x0+r*cos(a0+angle);
        *y=y0+r*sin(a0+angle);
    }
    else
    {
        *x=x0+r*cos(a0-angle);
        *y=y0+r*sin(a0-angle);
    }
}
//功能:设置旋转角度
void SetAngle(float angle)
{
    _RoateValue.angle=RADIAN(angle);
}
//功能:设置旋转方向 1为逆时针，0为顺时针
void SetAnggleDir(int direction)
{
    _RoateValue.direct=direction;
}
//功能:设置旋转中心点
void SetRotateCenter(int x0,int y0)
{
    _RoateValue.center.x=x0;
    _RoateValue.center.y=y0;
}
//功能:设置角度（只有这个函数是角度值，其它的都是弧度制）、旋转方向、旋转中心
void SetRotateValue(int x,int y,float angle,int direct)
{
    SetRotateCenter(x,y);
    SetAnggleDir(direct);
    SetAngle(angle);
}
//功能:将一个坐标旋转一定角度
//x,y:需要旋转的坐标
//return：旋转后的坐标
TypeXY GetRotateXY(int x,int y)
{
    TypeXY temp;
    int m=x,n=y;

    Rotate(_RoateValue.center.x,_RoateValue.center.y,&m,&n, _RoateValue.angle,_RoateValue.direct);
    temp.x=m;
    temp.y=n;
    return temp;
}

/*
	该函数为整个工程的核心函数
*/
void RoundClock(int hours,int minute,int sec)
{
    unsigned char i=0;
    TypeXY hourspoint,minutepoint,secpoint,tmp1,tmp2,tmp3;

    //时针
    SetRotateValue(119,119,hours*30+(minute*30)/60+clock_angle,1); //设定旋转中心，旋转角度，旋转方向
    hourspoint=GetRotateXY(119,119-42-shirink_size);         //给出一个不在中心的点，计算出其旋转后的坐标
    LCD_DrawLine(119,119,hourspoint.x,hourspoint.y,WHITE);//画线
    //分针
    SetRotateValue(119,119,minute*6+(sec*6)/60+clock_angle,1);
    minutepoint=GetRotateXY(119,119-63-shirink_size);
    LCD_DrawLine(119,119,minutepoint.x,minutepoint.y,WHITE);
    //秒针
    SetRotateValue(119,119,sec*6+clock_angle,1);
    secpoint=GetRotateXY(119,119-84-shirink_size);
    LCD_DrawLine(119,119,secpoint.x,secpoint.y,RED);
    //表盘
    for(i=0; i<12; i++)
    {
        SetRotateValue(119,119,i*30+clock_angle,1);
        tmp1=GetRotateXY(119,119-119);
        tmp2=GetRotateXY(119,119-100-shirink_size);
        LCD_DrawLine(tmp1.x,tmp1.y,tmp2.x,tmp2.y,WHITE);
        /*表盘上的数字*/ //部分数字位置不能用旋转求取。所以做了一些微调
        SetRotateValue(119,111,i*30+clock_angle,1);
        if(i==0)
        {
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x-8,tmp3.y,12,2,WHITE,BLACK,16);
        }
        else if(i<6)
        {
//			SetRotateValue(119,119,i*30+clock_angle,1);
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x,tmp3.y,i,1,WHITE,BLACK,16);
        }
        else if(i<10)
        {
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x-8,tmp3.y,i,1,WHITE,BLACK,16);
        }
        else if(i<12)
        {
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x-8,tmp3.y,i,2,WHITE,BLACK,16);
        }
    }

    Draw_Circle(119,119,8,WHITE);//中心圆点
    Draw_Circle(119,119,120-shirink_size,WHITE); //外圈圆盘
}

/*
	该函数为整个工程的核心函数
*/
int clr_abs(int num)
{
    num = (num>0)?num:(-num);
    return num;
}
void RoundClock_CLR(int hours,int minute,int sec)
{
    TypeXY hourspoint,minutepoint,secpoint;
    static int CLR_M,CLR_S;
//	static int M_X,M_Y;
    if(CLR_S != sec)
    {
        CLR_S = sec;
        //秒针
        SetRotateValue(119,119,sec*6+clock_angle,1);
        secpoint=GetRotateXY(119,119-84-shirink_size);
        LCD_DrawLine(119,119,secpoint.x,secpoint.y,BLACK);

        LCD_DrawLine(119,119,secpoint.x,secpoint.y,BLACK);
        LCD_DrawLine(119,119+1,secpoint.x,secpoint.y+1,BLACK);
        LCD_DrawLine(119,119-1,secpoint.x,secpoint.y-1,BLACK);
        //分针
        if(sec%10==0)
        {
            SetRotateValue(119,119,minute*6+(sec*6)/60+clock_angle,1);
            minutepoint=GetRotateXY(119,119-63-shirink_size);
//            switch((minutepoint.x-119)*((minutepoint.y-119)-119))
//            {
//            //case 0:
					if(((minutepoint.x-119)>=0)&&((minutepoint.y-119)>=0))
                LCD_Fill(119,119,119+63,119+63,BLACK);
                //break;
            //case 1:
					else if(((minutepoint.x-119)>=0)&&((minutepoint.y-119)<=0))
                LCD_Fill(119,119-63,119+63,119,BLACK);
                //break;
            //case 2:
					else if(((minutepoint.x-119)<=0)&&((minutepoint.y-119)<=0))
                LCD_Fill(119-63,119-63,119+1,119+1,BLACK);
                //break;
            //case 3:
					else if(((minutepoint.x-119)<=0)&&((minutepoint.y-119)>=0))
                LCD_Fill(119-63,119,119,119+63,BLACK);
                //break;
            //}
//            LCD_DrawLine(119,119,minutepoint.x,minutepoint.y,BLACK);
//			LCD_DrawLine(119,119+1,minutepoint.x,minutepoint.y+1,BLACK);
//			LCD_DrawLine(119,119-1,minutepoint.x,minutepoint.y-1,BLACK);
//			LCD_DrawLine(119,119+2,minutepoint.x,minutepoint.y+2,BLACK);
//			LCD_DrawLine(119,119-2,minutepoint.x,minutepoint.y-2,BLACK);
        }
//		if((clr_abs(M_X-minutepoint.x)+clr_abs(M_Y-minutepoint.y))>120)
//		{
//			LCD_DrawLine(119,119,minutepoint.x,minutepoint.y,BLACK);
//			for(deltaangel = 0;deltaangel <42;deltaangel++)
//			{
//				SetRotateValue(119,119,minute*6+(sec*6)/60+clock_angle+deltaangel,1);
//				minutepoint=GetRotateXY(119,119-63-shirink_size);
//			}
//		}

    }
    if(CLR_M != minute)
    {
        CLR_M = minute;

        //时针
        SetRotateValue(119,119,hours*30+(minute*30)/60+clock_angle,1); //设定旋转中心，旋转角度，旋转方向
        hourspoint=GetRotateXY(119,119-42-shirink_size);         //给出一个不在中心的点，计算出其旋转后的坐标
//        LCD_DrawLine(119,119,hourspoint.x,hourspoint.y,BLACK);//画线
				if(((hourspoint.x-119)>=0)&&((hourspoint.y-119)>=0))
							LCD_Fill(119,119,119+42,119+42,BLACK);
							//break;
					//case 1:
				else if(((hourspoint.x-119)>=0)&&((hourspoint.y-119)<=0))
							LCD_Fill(119,119-42,119+42,119,BLACK);
							//break;
					//case 2:
				else if(((hourspoint.x-119)<=0)&&((hourspoint.y-119)<=0))
							LCD_Fill(119-42,119-42,119,119,BLACK);
							//break;
					//case 3:
				else if(((hourspoint.x-119)<=0)&&((hourspoint.y-119)>=0))
							LCD_Fill(119-42,119,119,119+42,BLACK);
    }
}

void RoundClock_CLR_ALL(int hours,int minute,int sec)
{
    unsigned char i=0;
    TypeXY hourspoint,minutepoint,secpoint,tmp1,tmp2,tmp3;

    //时针
    SetRotateValue(119,119,hours*30+(minute*30)/60+clock_angle,1); //设定旋转中心，旋转角度，旋转方向
    hourspoint=GetRotateXY(119,119-42-shirink_size);         //给出一个不在中心的点，计算出其旋转后的坐标
    LCD_DrawLine(119,119,hourspoint.x,hourspoint.y,BLACK);//画线
    //分针
    SetRotateValue(119,119,minute*6+(sec*6)/60+clock_angle,1);
    minutepoint=GetRotateXY(119,119-63-shirink_size);
    LCD_DrawLine(119,119,minutepoint.x,minutepoint.y,BLACK);
    //秒针
    SetRotateValue(119,119,sec*6+clock_angle,1);
    secpoint=GetRotateXY(119,119-84-shirink_size);
    LCD_DrawLine(119,119,secpoint.x,secpoint.y,BLACK);
    //表盘
    for(i=0; i<12; i++)
    {
        SetRotateValue(119,119,i*30+clock_angle,1);
        tmp1=GetRotateXY(119,119-119);
        tmp2=GetRotateXY(119,119-100-shirink_size);
        LCD_DrawLine(tmp1.x,tmp1.y,tmp2.x,tmp2.y,BLACK);
        /*表盘上的数字*/ //部分数字位置不能用旋转求取。所以做了一些微调
        SetRotateValue(119,111,i*30+clock_angle,1);
        if(i==0)
        {
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x-8,tmp3.y,12,2,BLACK,BLACK,16);
        }
        else if(i<6)
        {
//			SetRotateValue(119,119,i*30+clock_angle,1);
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x,tmp3.y,i,1,BLACK,BLACK,16);
        }
        else if(i<10)
        {
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x-8,tmp3.y,i,1,BLACK,BLACK,16);
        }
        else if(i<12)
        {
            tmp3=GetRotateXY(119,119-num_pos-shirink_size);
            LCD_ShowIntNum(tmp3.x-8,tmp3.y,i,2,BLACK,BLACK,16);
        }
    }

    Draw_Circle(119,119,8,BLACK);//中心圆点
    Draw_Circle(119,119,120-shirink_size,BLACK); //外圈圆盘
}
